package com.jnu.hc.jnuhcusercms.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jnu.hc.jnuhcusercms.domain.Users;
import com.jnu.hc.jnuhcusercms.dto.ResponseObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.springframework.web.servlet.HandlerInterceptor;
import com.jnu.hc.jnuhcusercms.controller.UserController;

import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if (token == null) {
            sendError(response, 401, "未提供Token");
            return false;
        }

        try {
            System.out.println(token);
            Claims claims = Jwts.parser()
                    .verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload();

            Users user = new ObjectMapper().readValue((String) claims.get("currentUser"), Users.class);
            request.setAttribute("user", user);
            System.out.println("token有效");
            return true;

        } catch (ExpiredJwtException ex) { //单独捕获过期异常
            sendError(response, 401, "Token已过期");
            return false;

        } catch (Exception ex) {
            sendError(response, 401, "无效Token");
            return false;
        }
    }

    // 封装错误响应方法
    private void sendError(HttpServletResponse response, int status, String message) throws IOException {
        response.setStatus(status);
        response.setContentType("application/json"); // 必须设置Content-Type
        response.getWriter().println(
                new ObjectMapper().writeValueAsString(
                        new ResponseObject(status, message)
                )
        );
    }
    private SecretKey getSigningKey() {
        byte[] keyBytes = Decoders.BASE64.decode("my1very1long1secret1at1least1321bytes1long1");
        return Keys.hmacShaKeyFor(keyBytes);}
}